关于Promise.catch()错误捕获机制的理解

您所在的位置:网站首页 promise 传参 关于Promise.catch()错误捕获机制的理解

关于Promise.catch()错误捕获机制的理解

2024-07-16 20:52| 来源: 网络整理| 查看: 265

描述: 关于catch方法MDN的描述是这样的:

Internally calls Promise.prototype.then on the object upon which is called, passing the parameters undefined and the onRejected handler received; then returns the value of that call (which is a Promise )。这里说到 :

.catch方法在内部也是调用的Promise.prototype.then方法中的reject状态下的方法,也就是calling obj.catch(onRejected)内部calls obj.then(undefined, onRejected);

它返回了一个失败的promise, 以及返回一个参数作为一个失败理由。值得注意的是这里返回的是一个已定型的promise,这个过程是promise从pending到reject的改变过程。

p.then((val) => console.log('fulfilled:', val)) .catch((err) => console.log('rejected', err)); // 等同于 p.then((val) => console.log('fulfilled:', val)) .then(null, (err) => console.log("rejected:", err));

如果 Promise 状态已经变成resolved,再抛出错误是无效的。

const promise = new Promise(function(resolve, reject) { resolve('ok'); throw new Error('test'); //会被忽略,不会被捕获,等于没有抛出 }); promise .then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) }); // ok

这里很好理解,就是catch是从pending到reject的状态改变,但是一个promise一旦resolve以后,状态就凝固了,无法再发生变化,因此会被忽略。

错误捕获 1. try...catch捕获错误

先来看看try...catch 语句的错误捕获机制:当多层嵌套try...catch出现时,内部的错误抛出会被最近一个catch ,直到最外层。当错误被内部的catch捕获后,就失效了。

try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); //catch try抛出的 错误 } finally { console.log("finally"); } } catch (ex) { console.error("outer", ex.message); //这里的代码不执行 } // Output: // "inner" "oops" // "finally"

再次抛出错误

try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); throw ex; //这里已经捕获到了异常,这个异常就失效了;如果这里不重新throw ex,外面的catch感知不到这里的异常的,即外层的catch{}不会执行 } finally { console.log("finally"); } } catch (ex) { console.error("outer", ex.message); //捕获 throw ex; } // Output: // "inner" "oops" // "finally" // "outer" "oops" 2. promise捕获错误

promise 错误捕获和try...catch一样会冒泡到外层。

promise的错误抛出后会一直传递到最外层,直到被捕获;当catch捕获错误以后,返回的还是一个promise对象,可以继续链式调用。

const p1 = new Promise((resolve, reject) => { setTimeout(() => resolve('成功'), 3000) }) const p2 = new Promise((resolve, reject) => { setTimeout(() => reject(new Error('失败了')), 3000) }) p1.then(function (post) { return p2 }) .then((resolve) => { //这里的代码不会执行 console.log('p2 reject 第二个then执行了') return `第二个then的返回值` }) .catch((e) => { console.log(e, '=====first error') }) .then((resolve) => { console.log('第三个then执行了,接收到的返回值为:', resolve) }) .catch((e) => console.log(e, '=====error')) // Error: 失败了 at eval (test.js?33a7:92) "=====first error" // console.log('第三个then执行了,接收到的返回值为:', resolve)

如果.then()方法后面没有catch方法,后面紧跟着的链式调用的.then()不会执行。

p1.then(function (post) { return p2 }) .then((resolve) => { //这里的代码不会执行 console.log('p2 reject 第二个then执行了') return `第二个then的返回值` }) .then((resolve) => { //这里的代码不会执行 console.log('第三个then执行了,接收到的返回值为:', resolve) }) .catch((e) => console.log(e, '=====error')) // Error: 失败了 at eval (test.js?33a7:92) "=====error" 3. 区别:

prmise跟传统的try/catch代码块不同的是,如果没有使用catch()方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。

try { try { throw new Error("oops"); } catch (ex) { // console.error('inner', ex.message) // throw ex } finally { console.log("finally"); } } catch (ex) { console.error("outer", ex.message); // 捕获 throw ex; } // finally

上面的代码,catch代码块捕获了错误,但是进行错误处理,浏览器也不会自动抛出错误,会跳过这段错误。

但如果是promise则会传递未捕获的错误,浏览器会自动抛错。

p1.then(function (post) { return p2 }) .then((resolve) => { console.log('p2 reject 第二个then执行了') return `第二个then的返回值` }) // Uncaught (in promise) Error: 失败了 // at eval (test.js?33a7:92)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3